package com.apps.express.Express100.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apps.express.Express100.config.Express100Config;
import com.apps.express.Express100.enums.ExpressStatus;
import com.apps.express.Express100.model.po.Express;
import com.apps.express.Express100.model.po.ExpressItem;
import com.apps.express.Express100.model.vo.SendParamVo;
import com.apps.express.Express100.service.IExpressService;
import com.apps.express.Express100.utils.MD5Utils;
import com.apps.sannotation.constraints.NoNull;
import com.apps.saspect.ValidMethod;
import com.apps.sexctption.NullException;
import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 快递100查询
 */
@Slf4j
@Component
public class IExpress100ServiceImpl implements IExpressService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private Express100Config express100Config;

    /**
     * 根据快递单号返回快递公司编码,这个不是百分百准确.慎用.
     * @param ship_number
     * @return
     */
    @ValidMethod
    protected List<String> autoNumber(@NoNull(errMsg = "快递单号不能为空") String ship_number)
    {
        String api="http://www.kuaidi100.com/autonumber/auto?num={num}&key={key}";
        JSONArray array=JSON.parseArray(restTemplate.getForObject(api,String.class,ship_number,express100Config.getKey()));
        if(null == array || array.size() <= 0)
            return null;
        List<String> result=new ArrayList<>();
        for(int i=0;i<array.size();i++)
            result.add(array.getJSONObject(i).getString("comCode"));
        return result ;
    }


    /**
     * 将快递100的接口返回的JSON对象转化成本项目的实体对象
     * 这个方法之所以写在这里，是因为后期可能集成其它快递平台接口来增加健壮性，这样Express的构造就不该由它自己决定.
     * @param jsonObject
     * @return
     */
    @ValidMethod
    protected Express conversion(@NoNull(errMsg = "json数据不能为空") JSONObject jsonObject)
    {
        Express result=new Express();
        result.setCompany_code(jsonObject.getString("com"));
        result.setIsComplete(jsonObject.getInteger("ischeck"));
        result.setShip_number(jsonObject.getString("nu"));
        result.setState(jsonObject.getInteger("state"));
        //处理快递明细
        List<ExpressItem> expressItems=new ArrayList<>();
        JSONArray jsonArray=jsonObject.getJSONArray("data");
        for(int i=0;i<jsonArray.size();i++)
        {
            ExpressItem item=new ExpressItem();
            item.setContent(jsonArray.getJSONObject(i).getString("context"));
            item.setGmt_create(jsonArray.getJSONObject(i).getTimestamp("time").toLocalDateTime());
            item.setStatus(ExpressStatus.getCodeByKudi100(jsonArray.getJSONObject(i).getString("status")).getCode());
            expressItems.add(item);
        }
        result.setData(expressItems);
        //处理快递路由信息
        result.setExpressRoute(jsonObject.getJSONObject("routeInfo"));
        return result;
    }

    /**
     * 用快递单号查询快递信息,智能查单
     * @param ship_no
     * @return
     */
    @ValidMethod
    @Override
    public Express queryExpress(@NoNull(errMsg = "快递单号不能为空") String ship_no)
    {
        List<String> es_logi_company_code = autoNumber(ship_no);
        if(CollectionUtil.isEmpty(es_logi_company_code))
            throw new NullException("商家填写单号错误或者是未知的小快递公司,请联系商家处理");
        //逐个识别
        for(String code:es_logi_company_code) {
            Express express=queryExpress(ship_no,code);
            if(null != express)
                return express;
        }
        return null;
    }

    /**
     * 最基础的实时查询单号方法
     * @param ship_no
     * @param companyCode
     * @return
     */
    @ValidMethod
    @Override
    public Express queryExpress(@NoNull(errMsg = "快递单号不能为空") String ship_no,
                                @NoNull(errMsg = "快递公司代码不能为空") String companyCode)
    {
        String api="http://poll.kuaidi100.com/poll/query.do?customer={customer}&sign={sign}&param={json}";
        SendParamVo paramVo=new SendParamVo(companyCode,ship_no);
        JSONObject data=JSONObject.parseObject(restTemplate.getForObject(api,String.class,express100Config.getCustomer().toUpperCase(), MD5Utils.encode(JSONObject.toJSON(paramVo) + express100Config.getKey() + express100Config.getCustomer()),JSONObject.toJSON(paramVo)));
        if(!data.getString("message").equals("ok"))
            return null;
        return conversion(data);
    }



}
